#pragma once

/*单例配置类：使用文件配置加载一些程序的运行关键信息，可以使程序的运行更加灵活
    1.热点判断时间
        热点管理：多长时间没有被访问的文件算是非热点文件
    2.文件下载的url前缀路径--用于表示客户端的请求是一个下载请求
        /listshow：访问请求
        /download/listshow：下载请求
    3.压缩包后缀名
        ".lz"
    4.上传文件存放路径
        决定了文件上传之后实际存储再服务器的哪里
    5.压缩包存放路径
        决定非热点文件压缩后存放的路径
    6.服务端备份信息存放文件
        服务端记录的备份文件信息的持久化存储
    7.服务器的监听IP + port
        当程序要运行在其他主机上，则不需要修改程序
*/

#include <mutex>

#include "util.hpp"

namespace cloud
{
    #define CONFIG_FILE "./cloud.conf"
    class Config
    {
    private:
        Config()
        {
            ReadConfigFile();
        }

        static Config *_instance;
        static std::mutex _mutex;

    public:
        static Config *GetInstance()
        {
            if(_instance == nullptr)
            {
                _mutex.lock();
                if(_instance == nullptr)
                {
                    _instance = new Config();
                }
                _mutex.unlock();
            }
            return _instance;
        }

        time_t GetHotTime()
        {
            return _hot_time;
        }
        int GetServerPort()
        {
            return _server_port;
        }
        std::string GetServerIp()
        {
            return _server_ip;
        }
        std::string GetDownloadPrefix()
        {
            return _download_prefix;
        }
        std::string GetPackFileSuffix()
        {
            return _packfile_suffix;
        }
        std::string GetPackDir()
        {
            return _pack_dir;
        }
        std::string GetBackDir()
        {
            return _back_dir;
        }
        std::string GetBackupFile()
        {
            return _backup_file;
        }

        bool ReadConfigFile()
        {
            FileUtil fu(CONFIG_FILE);
            std::string body;
            if(!fu.GetContent(&body))
            {
                std::cout << "load config file failed" << std::endl;
                return false;
            }
            Json::Value root;
            if(!JsonUtil::Unserialize(body, &root))
            {
                std::cout << "parse config file failed" << std::endl;
                return false;
            }

            _hot_time = root["hot_time"].asInt();
            _server_port = root["server_port"].asInt();
            _server_ip = root["server_ip"].asString();
            _download_prefix = root["download_prefix"].asString();
            _packfile_suffix = root["packfile_suffix"].asString();
            _pack_dir = root["pack_dir"].asString();
            _back_dir = root["back_dir"].asString();
            _backup_file = root["backup_file"].asString();

            return true;
        }
    private:
        time_t _hot_time;             // 热点判断时间
        int _server_port;             // 服务器监听端口
        std::string _download_prefix; // 下载的url前缀路径
        std::string _packfile_suffix; // 压缩包的后缀名称
        std::string _back_dir;        // 备份文件存放目录
        std::string _pack_dir;        // 压缩包存放目录
        std::string _server_ip;       // 服务器ip地址
        std::string _backup_file;     // 数据信息存放文件
    };

    Config* Config::_instance = nullptr;
    std::mutex Config::_mutex;

}
